package cat.joronya.supermanager.market;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Locale;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
import cat.joronya.supermanager.R;
import cat.joronya.supermanager.Supermanager;
import cat.joronya.supermanager.service.SupermanagerServiceHelper;
import cat.joronya.supermanager.utils.ImageDownloader;

public class MarketListFragment extends ListFragment 
	implements LoaderManager.LoaderCallbacks<Cursor>, MarketListActivity.OnChangeFilter
{
	// pel Log
	private static final String TAG = "supermanager";
	
	public static final String POSITION_GUARDS = "GUARD";
	public static final String POSITION_FORWARDS = "FORWARD";
	public static final String POSITION_CENTERS = "CENTER";
	
	private static final String UP_ARROW = "\u2191";
	private static final String DOWN_ARROW = "\u2193";
	
	/**
     * The columns we are interested in from the database
     */
    private static final String[] PROJECTION = new String[] {
            "m."+Supermanager.Market._ID, 			// 0
            Supermanager.Market.ID_PLAYER,			// 1
            Supermanager.Market.STATUS,				// 2
            Supermanager.Market.NACIONALITY,		// 3
            Supermanager.Market.NAME, 				// 4
            Supermanager.Market.INFO,				// 5
            Supermanager.Market.TEAM,				// 6
            Supermanager.Market.BALANCE,			// 7
            Supermanager.Market.AVERAGE,			// 8
            Supermanager.Market.PRICE,				// 9
            "m."+Supermanager.Market.MODIFIED_DATE, // 10
            "m."+Supermanager.Market.CODI_PLAYER,	// 11
            Supermanager.Market.SHOWN_IN_BUY,		// 12
            Supermanager.Market.COLOR_IN_BUY,		// 13
            Supermanager.Market.RATING,				// 14
            Supermanager.Market.RATING_LAST3_GAMES,	// 15
            Supermanager.Market.INCREASE_15,		// 16
            Supermanager.Market.KEEP_PRICE,			// 17
            Supermanager.Market.DECREASE_15,		// 18
            Supermanager.Market.VS_TEAM,			// 19
            Supermanager.PlayerList.LIST_NAME,		// 20
            Supermanager.Market.MINUTES				// 21
    };
    
    //private Cursor daysCursor = null;
	private String jornada = "undefined";
	public static final int GUARDS = 0;
	public static final int FORWARDS = 1;
	public static final int CENTERS = 2;
	private int selectedPosition = GUARDS;
	
	// buying player from MyTeamDetail, store position demanded
	private String idequ = null;
	private String buyPosition = null;
	private String buyCash = null;
    
	// Gesture detection
    protected MySimpleOnGestureListener mySimpleOnGestureListener;
	protected GestureDetector myGestureDetector;
	protected boolean showingPlayerInfo = false;
	
	protected AbsListView absListView;
	protected ViewFlipper viewFlipper;
	protected static final int SWIPE_MIN_DISTANCE = 60;
	protected static final int SWIPE_MAX_OFF_PATH = 250;
	protected static final int SWIPE_THRESHOLD_VELOCITY = 200;
    
	protected Animation slideLeftIn;
	protected Animation slideLeftOut;
	protected Animation slideRightIn;
	protected Animation slideRightOut;
	
	private NumberFormat decform = null;
    private NumberFormat intform = null;
    
    // filter position: guard, forward or center
    private String position = null;
    
    private ImageDownloader imageDownloader;

    // order clause with default
	private String order = Supermanager.Market.DEFAULT_SORT_ORDER;
	// mantain order of order clause in pickpup list
	private int orderOnPickupList = 0;
	
	// loader id
	private static final int LIST_LOADER = 0x01;
	
	// the adapter
	private MarketAdapter adapter;
	
	private OnFavListener mFavListener;
	private OnBuyListener mBuyListener;
	private OnSortListener mSortListener;
	
	protected String mFilter = null; 
    
	
	/**
     * Create a new instance of DetailsFragment, initialized to
     * show the text at 'index'.
     */
    public static MarketListFragment newInstance(String idequ, String buyPosition, String buyCash, String position, String jornada) 
    {
    	MarketListFragment f = new MarketListFragment();

        // Supply index input as an argument.
        Bundle args = new Bundle();
        args.putString("cat.joronya.supermanager.myteamdetail.idequ", idequ);
        args.putString("cat.joronya.supermanager.myteamdetail.position", buyPosition);
        args.putString("cat.joronya.supermanager.myteamdetail.cash", buyCash);
        args.putString("cat.joronya.supermanager.market.position", position);
        args.putString("cat.joronya.supermanager.market.jornada", jornada);
        f.setArguments(args);

        return f;
    }
    
    /*
     * Listener that should implement activity to allow show/dissmiss fav dialog.
     */
    public interface OnFavListener {
    	public void showFavDialog(String list);
    	public void dissmissFavDialog();
    }
    
    public interface OnBuyListener {
    	public void showBuyDialog(String idequ, String idjug, String name, boolean selectable);
    	public void dissmissBuyDialog();
    }
    
    public interface OnSortListener {
    	public void showSortDialog(int checked);
    	public void dissmissSortDialog();
    }
    
    @Override
    public void onAttach(Activity activity) 
    {
        super.onAttach(activity);

        try {
            mFavListener = (OnFavListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnFavListener");
        }
        try {
            mBuyListener = (OnBuyListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnBuyListener");
        }
        try {
            mSortListener = (OnSortListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnSortListener");
        }
    }
    
    @Override
    public void onDetach() {
      super.onDetach();
      mFavListener = null;
      mBuyListener = null;
      mSortListener = null;
      
      // register fragment as listener for filter changes
      MarketListActivity marketActivity  = (MarketListActivity)getActivity();
      marketActivity.removeChangeFilterListener(this);
      
      getLoaderManager().destroyLoader(LIST_LOADER);
    }
    
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) 
	{
		View view = inflater.inflate(R.layout.market, null);
		
		return view;
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) 
	{
		super.onActivityCreated(savedInstanceState);
		
		// initialize image downloader
		imageDownloader = new ImageDownloader(getActivity().getApplicationContext(), Supermanager.PLAYERS, 70);
		
		// avisem q el fragment te menu pq es cridi
        setHasOptionsMenu(true);
        
        // have we come from MyTeamDetail to buy player?
        Bundle args = getArguments();
        if( args != null )
        {
        	idequ = args.getString("cat.joronya.supermanager.myteamdetail.idequ");
        	buyPosition = args.getString("cat.joronya.supermanager.myteamdetail.position");
        	buyCash = args.getString("cat.joronya.supermanager.myteamdetail.cash");
        	position = args.getString("cat.joronya.supermanager.market.position");
        	jornada = args.getString("cat.joronya.supermanager.market.jornada");
        }
        
        if( decform == null )
        {
        	decform = NumberFormat.getNumberInstance(new Locale("es","ES"));
        	decform.setMinimumFractionDigits(2);
        }
        if( intform == null )
        {
        	intform = NumberFormat.getNumberInstance(new Locale("es","ES"));
        	intform.setGroupingUsed(true);
        }
        
        // load animations
       	slideLeftIn = AnimationUtils.loadAnimation(getActivity().getApplicationContext(), R.anim.slide_left_in);
        slideLeftOut = AnimationUtils.loadAnimation(getActivity().getApplicationContext(), R.anim.slide_left_out);
        slideRightIn = AnimationUtils.loadAnimation(getActivity().getApplicationContext(), R.anim.slide_right_in);
        slideRightOut = AnimationUtils.loadAnimation(getActivity().getApplicationContext(), R.anim.slide_right_out);
        
        // create gesture listener and detector
		mySimpleOnGestureListener = new MySimpleOnGestureListener();
		myGestureDetector = new GestureDetector(getActivity().getApplicationContext(), mySimpleOnGestureListener);
		
		// default order
        SharedPreferences settings = 
    		PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
        orderOnPickupList = Integer.valueOf(settings.getString(Supermanager.PREFS_MARKET_ORDER, "0"));
        
        // triem criteri ordenacio inicial per defecte
        switch(orderOnPickupList)
        {
        	case 0:
        		order = Supermanager.Market.PRICE_SORT_ORDER;
        		break;
        	case 1:
        		order = Supermanager.Market.AVERAGE_SORT_ORDER;
        		break;
        	case 2:
        		order = Supermanager.Market.RATING_SORT_ORDER;
        		break;
        	case 3:
        		order = Supermanager.Market.RATING_LAST3_GAMES_SORT_ORDER;
        		break;
        	case 4:
        		order = Supermanager.Market.INCREASE_15_SORT_ORDER;
        		break;
        	case 5:
        		order = Supermanager.Market.KEEP_PRICE_SORT_ORDER;
        		break;
        	case 6:
        		order = Supermanager.Market.DECREASE_15_SORT_ORDER;
        		break;
       	}
        
        // refresh order mark on header
        updateHeaderOrderMark();
        
        showMarket(position);
        
        // create market adapter and assign it to view 
        adapter= new MarketAdapter(getActivity().getApplicationContext(), null);
        setListAdapter(adapter);
        
        // register fragment as listener for filter changes
        // call it in onAttach is too soon and no initialised jornada and position
        MarketListActivity marketActivity  = (MarketListActivity)getActivity();
        marketActivity.addChangeFilterListener(this);
        mFilter = marketActivity.getCurrentListName();
        
        // initialize the loader
        getLoaderManager().initLoader(LIST_LOADER, null, this);
	}
	
	 @Override
	 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
	 {
		 inflater.inflate(R.menu.market, menu);
	     super.onCreateOptionsMenu(menu, inflater);
	 }

	 @Override
	 public boolean onOptionsItemSelected(MenuItem item) 
	 {
		 // Handle item selection
		 switch (item.getItemId()) 
		 {
		 case R.id.order:
			 mSortListener.showSortDialog(orderOnPickupList);
			 return true;
		 case R.id.refresh:
			 Log.d(TAG,"refreshing market player list");
			 // cridar refresh al REST method
			 SupermanagerServiceHelper.getInstance(getActivity().getApplicationContext()).getMarket(handler);
			 return true;
		 default:
			 return super.onOptionsItemSelected(item);
		 }
	 }
	 
	 public void changeSortCriteria(int item)
	 {
		// mantain pick up element
	    orderOnPickupList = item;
	        
	    switch(item)
	    {
	    	case 0:
	    		order = Supermanager.Market.PRICE_SORT_ORDER;
	    		break;
	    	case 1:
	    		order = Supermanager.Market.AVERAGE_SORT_ORDER;
	    		break;
	    	case 2:
	    		order = Supermanager.Market.RATING_SORT_ORDER;
	    		break;
	    	case 3:
	    		order = Supermanager.Market.RATING_LAST3_GAMES_SORT_ORDER;
	    		break;
	    	case 4:
	    		order = Supermanager.Market.INCREASE_15_SORT_ORDER;
	    		break;
	    	case 5:
	    		order = Supermanager.Market.KEEP_PRICE_SORT_ORDER;
	    		break;
	    	case 6:
	    		order = Supermanager.Market.DECREASE_15_SORT_ORDER;
	    		break;
	    }
	    
	    // refresh order mark on header
        updateHeaderOrderMark();
        
        // mostrem dades altre cop
        switch (selectedPosition) 
    	{
        	default:
    		case GUARDS:
    			showMarket(POSITION_GUARDS);
    			break;
    		case FORWARDS:
    			showMarket(POSITION_FORWARDS);
    			break;
    		case CENTERS:
    			showMarket(POSITION_CENTERS);
    			break;
    	}
        
        // resetejem el loader per canviar l'ordenacio
        getLoaderManager().restartLoader(LIST_LOADER, null, this);
        
        // tanquem el dialog
        mSortListener.dissmissSortDialog();
	 }
	 
	 /**
	  * Respon al click del fav, toggle l'afegit a favorits del jugador.
	  * @param view
	  */
	 public void favPlayer(View view)
	 {
		 final String cod = (String)view.getTag(R.id.player);
		 final String list = (String)view.getTag(R.id.player_name);
		 Log.d(TAG, "Toggle list: "+list+", on player: "+cod);

		 // mostrem el fav dialog a l'activity
		 mFavListener.showFavDialog(list);
		 
		 // fem la feina en background
		 new Thread() 
		 {
			 public void run() 
			 {
				 // si list es null, doncs es un insert
				 if( list == null )
				 {
					 ContentValues values = new ContentValues();
					 values.put(Supermanager.PlayerList.CODI_PLAYER, cod);
					 values.put(Supermanager.PlayerList.LIST_NAME, Supermanager.FAV_LISTNAME);

					 getActivity().getContentResolver().insert(Supermanager.PlayerList.CONTENT_URI, values);
					 Log.d(TAG, "Player["+cod+"] added to list["+Supermanager.FAV_LISTNAME+"]");
				 }
				 // altrament es un delete per remove de list favorites
				 else
				 {
					 String where = Supermanager.PlayerList.CODI_PLAYER+" = ? AND "+
					 Supermanager.PlayerList.LIST_NAME+" = ? ";
					 String[] selectionArgs = new String[]{cod,Supermanager.FAV_LISTNAME};
					 getActivity().getContentResolver().delete(Supermanager.PlayerList.CONTENT_URI, where, selectionArgs);
					 Log.d(TAG, "Player["+cod+"] removed from list["+Supermanager.FAV_LISTNAME+"]");
				 }
				 
				 // un cop acabat, tanquem el fav progress dialog
				 mFavListener.dissmissFavDialog();

				 // tornem el flipper a lloc
				 MarketListFragment.this.getActivity().runOnUiThread(new Runnable(){
					 public void run(){
						 mySimpleOnGestureListener.showPreviousOnFlingedRow();
					 }
				 });
			 }
		 }.start();

	 }
	 
	 /**
	  * Respon al click del buy, alert i accio de buy.
	  * @param view
	  */
	 public void buyPlayer(View view)
	 {
		 // if we are in buy, is player selectable?
		 boolean selectable = (Boolean) view.getTag(R.id.stick);

		 // if we are not buying or not selectable, nothing to do here
		 if( buyPosition == null || !selectable )
		 {
			 return;
		 }
		 
		 // data to show alert to confirm buying this player
		 String idjug = (String)view.getTag(R.id.market_player);
		 String name = (String)view.getTag(R.id.player_name);
		 
		 // mostrem dialog
		 mBuyListener.showBuyDialog(idequ, idjug, name, selectable);
	 }

	 /**
	  * Respon al +info button deshabilitant la list i mostrant
	  * el boto de info.
	  * @param view
	  */
	 public void showPlayerInfo(View view) 
	 {
		 // disable list events and grey it
		 ListView list = getListView();
		 list.setEnabled(false);
		 showingPlayerInfo = true;

		 // enable info button over grey list 
		 Button infoButton = (Button)getView().findViewById(R.id.player_info);
		 infoButton.setText(view.getTag().toString());
		 infoButton.setVisibility(View.VISIBLE);
		 infoButton.setOnClickListener(new OnClickListener() 
		 {
			public void onClick(View view) 
			{
				hidePlayerInfo(view);
			}
		});
	 }

	 /**
	  * Respon al click de la info 'modal'. Amaga info i habilita
	  * la list.
	  * @param view
	  */
	 public void hidePlayerInfo(View view) 
	 {
		 // disable info button
		 Button infoButton = (Button)getView().findViewById(R.id.player_info);
		 infoButton.setVisibility(View.GONE);

		 // enable list events and grey off
		 ListView list = getListView();
		 list.setEnabled(true);
		 showingPlayerInfo = false;
	 }

	 private Handler handler = new Handler() 
	 { 
		 @Override 
		 public void handleMessage(Message msg)
		 { 
			 //get data from msg 
			 int status = msg.getData().getInt(Supermanager.STATUS_MESSAGE);
			 Log.d(TAG, "MarketListActivity received status: "+status);

			 if( status == Supermanager.MARKET_PARSED_OK )
			 {
				 // recuperem la jornada, per si em parsejat nova jornada
				 //getDaysOfMarket();

				 // mostrem dades altre cop
				 switch (selectedPosition) 
				 {
				 default:
				 case GUARDS:
					 showMarket(POSITION_GUARDS);
					 break;
				 case FORWARDS:
					 showMarket(POSITION_FORWARDS);
					 break;
				 case CENTERS:
					 showMarket(POSITION_CENTERS);
					 break;
				 }

				 Toast.makeText(getActivity().getApplicationContext(), 
						 R.string.market_toast_refresh_done, 
						 Toast.LENGTH_SHORT).show();
			 }
			 else if( status == Supermanager.CLOSED_STATUS )
			 {
				 // amaguem el ProgressBar
				 Toast.makeText(getActivity().getApplicationContext(), 
						 R.string.market_toast_refresh_fail_changes_closed, 
						 Toast.LENGTH_SHORT).show();
			 }
			 // altrament error
			 else
			 {
				 Toast.makeText(getActivity().getApplicationContext(), 
						 R.string.market_toast_refresh_fail, 
						 Toast.LENGTH_SHORT).show();
			 }

			 super.handleMessage(msg); 
		 } 
	 };
	 
    /**
     * Refresh header order arrow mark on every header to notice
     * which order criteria is enabled.
     */
    private void updateHeaderOrderMark()
    {
    	// hide all arrows, so first default string
    	TextView priceView = (TextView)getView().findViewById(R.id.market_price);
    	priceView.setText(getString(R.string.market_price));
    	TextView averageView = (TextView)getView().findViewById(R.id.market_average);
    	averageView.setText(getString(R.string.market_average));
    	TextView ratingView = (TextView)getView().findViewById(R.id.market_rating);
    	ratingView.setText(getString(R.string.market_rating));
    	TextView ratingL3GView = (TextView)getView().findViewById(R.id.market_rating_last3_games);
    	ratingL3GView.setText(getString(R.string.market_last3_games));
    	TextView increase15View = (TextView)getView().findViewById(R.id.market_increase15);
    	increase15View.setText(getString(R.string.market_increase15));
    	TextView keepPriceView = (TextView)getView().findViewById(R.id.market_keep_price);
    	keepPriceView.setText(getString(R.string.market_keep_price));
    	TextView decrease15View = (TextView)getView().findViewById(R.id.market_decrease15);
    	decrease15View.setText(getString(R.string.market_decrease15));
    	
    	// venim de buy del my team detail?
    	TextView cashLabelView = (TextView)getView().findViewById(R.id.market_cash_label);
    	TextView cashView = (TextView)getView().findViewById(R.id.market_cash);
    	RelativeLayout segonaLinia = (RelativeLayout)getView().findViewById(R.id.segona_linia);
    	if( buyCash == null )
    	{
    		if( segonaLinia != null )
    		{
    			// ocultem linia superior nomes si no estem al portrait normal
    			String tag = (String)segonaLinia.getTag();
    			if( "normal-portrait".equals(tag) )
    				segonaLinia.setVisibility(View.VISIBLE);
    			else
    				segonaLinia.setVisibility(View.GONE);
    		}
    		cashLabelView.setVisibility(View.GONE);
    		cashView.setVisibility(View.GONE);
    	}
    	else
    	{
    		if( segonaLinia != null )
    		{
    			segonaLinia.setVisibility(View.VISIBLE);
    			
    			// mostrem linia superior nomes si estem al portrait normal
    			/*String tag = (String)segonaLinia.getTag();
    			if( "normal-portrait".equals(tag) )
    				segonaLinia.setVisibility(View.GONE);
    			else
    				segonaLinia.setVisibility(View.VISIBLE);*/
    		}
    		cashLabelView.setVisibility(View.VISIBLE);
    		cashView.setText(buyCash);
    		cashView.setVisibility(View.VISIBLE);
    	}
    	
    	// set price arrow
    	switch( orderOnPickupList )
    	{
    		case 0:
    			priceView.setText(getString(R.string.market_price)+DOWN_ARROW);
    			break;
    		case 1:
    			averageView.setText(getString(R.string.market_average)+DOWN_ARROW);
    			break;
    		case 2:
    			ratingView.setText(getString(R.string.market_rating)+DOWN_ARROW);
    			break;
    		case 3:
    			ratingL3GView.setText(getString(R.string.market_last3_games)+DOWN_ARROW);
    			break;
    		case 4:
    			increase15View.setText(getString(R.string.market_increase15)+UP_ARROW);
    			break;
    		case 5:
    			keepPriceView.setText(getString(R.string.market_keep_price)+UP_ARROW);
    			break;
    		case 6:
    			decrease15View.setText(getString(R.string.market_decrease15)+UP_ARROW);
    			break;
    	}
    }

    private void showMarket(String position)
    {
    	// guardem la posicio mostrada
        this.position = position;

        if( POSITION_GUARDS.equals(position) )
        {
        	selectedPosition = GUARDS;
        }
        else if( POSITION_FORWARDS.equals(position) )
        {
        	selectedPosition = FORWARDS;
        }
        else if( POSITION_CENTERS.equals(position) )
        {
        	selectedPosition = CENTERS;
        }
	}
    
	/**
	 * Gesture listener that responds to:
	 * -fling showing action buttons, +info...
	 * -onLongPress selecting player in buy action from MyTeam.
	 */
	class MySimpleOnGestureListener extends SimpleOnGestureListener 
	{
		private ViewFlipper viewFlipper = null;
		private boolean flipperChanged = false;
		private boolean flipperLongPressed = false;
		
		/**
		 * Sets the view flipper of the last row flinged, so on any event on list,
		 * return view flipper registered to initial status, so hide buttons.
		 * @param theViewFlipper
		 */
		public void setViewFlipper(ViewFlipper theViewFlipper)
		{
			// si tenim longPress pero al mateix flipper, no fem res
			if( flipperLongPressed && viewFlipper == theViewFlipper )
			{
				//Log.d(TAG, "MySimpleOnGestureListener.setViewFlipper longPress and the same flipper, nothing to do.");
				return;
			}
			
			// si ens canvien el flipper, mostrem 1a vista del flipper
			if( viewFlipper != theViewFlipper )
			{
				//Log.d(TAG, "MySimpleOnGestureListener.setViewFlipper different flipper, show previos view.");
				showPreviousOnFlingedRow();
			}
			
			// registrem el flipper de la fila nova
			viewFlipper = theViewFlipper;
		}
		
		/**
		 * For calling externally and return the row to first status.
		 */
		public void showPreviousOnFlingedRow()
		{
			// si el flipper estava canviat, el tornem a lloc
			if( flipperChanged )
			{
				viewFlipper.setInAnimation(slideRightIn);
                viewFlipper.setOutAnimation(slideRightOut);
				viewFlipper.showPrevious();
				flipperChanged = false;
			}
		}
		
		/**
		 * Overriden to avoid 'bug' and prevent onFling from not being called as
		 * described in http://code.google.com/p/android/issues/detail?id=8233
		 */
		@Override
		public boolean onDown(MotionEvent e)
		{
			//Log.d(TAG, "MySimpleOnGestureListener.onDown");
			
			// desmarquem possible previ onLongPress
			flipperLongPressed = false;
			
			return true;
		}
		
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) 
        {
            try 
            {
            	//Log.d(TAG, "MySimpleOnGestureListener.onFling");
            	if( Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH )
                    return false;
                
                // left to right swipe, left fling
                if( e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY ) 
                {
       				flipperChanged = true;
       				viewFlipper.setInAnimation(slideLeftIn);
       				viewFlipper.setOutAnimation(slideLeftOut);
       				viewFlipper.showNext();
                }  
                else if(e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY )
                {
                	// nothing to do on right fling
                }
            	return true;
            }
            catch(Exception e){
                // nothing
            }
            return false;
        }
        
        @Override
        public void onLongPress(MotionEvent e)
        {
        	//Log.d(TAG, "MySimpleOnGestureListener.onLongPress");
        	flipperChanged = true;
			flipperLongPressed = true;
			viewFlipper.setInAnimation(slideLeftIn);
			viewFlipper.setOutAnimation(slideLeftOut);
			viewFlipper.showNext();
        }
    }
	
    /**
     * Adapter to customize easily list item layout and values.
     * @author pol
     *
     */
    class MarketAdapter extends CursorAdapter 
	{
    	public Drawable defaultDrawable; 
    	
		public MarketAdapter(Context theContext, Cursor theCursor) 
		{
			super(theContext, theCursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
			defaultDrawable = theContext.getResources().getDrawable(R.drawable.noplayer);
		}
		
		@Override
		public void bindView(View view, Context context, Cursor cursor) 
		{
			//Log.d(TAG,"MarketListActivity bindView for player: "+name);
			
			// set player name
			String name = cursor.getString(4);
			TextView nameView = (TextView)view.findViewById(R.id.player_name);
			nameView.setText(name);
			
			// get idjug, and only set it to tag of the view when black color
			String idJug = cursor.getString(1);

			// show buy button market_row_buy_button
			TextView buyView = (TextView)view.findViewById(R.id.player_buy_button);
			Button buyButton = (Button)view.findViewById(R.id.market_row_buy_button);
			buyButton.setOnClickListener(new OnClickListener() 
			{
				public void onClick(View view) 
				{
					buyPlayer(view);
				}
			});
			
			// if we are in buy view, set color of player name and buttons
			if( buyPosition != null )
			{
				// set player name to tag for display
				buyButton.setTag(R.id.player_name, name);
				
				// set player idjug to buy
				buyButton.setTag(R.id.market_player, idJug);

				// depenent del color el jugador sera comprable o no
				String color = cursor.getString(13);
				if( Supermanager.Market.RED_COLOR.equals(color.toUpperCase()) )
				{
					nameView.setTextColor(Color.RED);//0xFFF0000);

					// comprant, mostrem botons
					buyView.setVisibility(View.GONE);
					buyButton.setVisibility(View.GONE);

					// player not selectable
					buyButton.setTag(R.id.stick, false);
				}
				else if( Supermanager.Market.ORANGE_COLOR.equals(color.toUpperCase()) )
				{
					nameView.setTextColor(0xFFFC7219);

					// comprant, mostrem botons
					buyView.setVisibility(View.GONE);
					buyButton.setVisibility(View.GONE);

					// player not selectable
					buyButton.setTag(R.id.stick, false);
				}
				else
				{
					nameView.setTextColor(Color.BLACK);

					// comprant, mostrem botons
					buyView.setVisibility(View.VISIBLE);
					buyButton.setVisibility(View.VISIBLE);

					// player selectable
					buyButton.setTag(R.id.stick, true);
				}
			}
			// not buying so, invisible buy buttons
			else
			{
				// no venim del myTeamDetail per comprar
				buyView.setVisibility(View.GONE);
				buyButton.setVisibility(View.GONE);
				
				// by default player not selectable
				buyButton.setTag(R.id.stick, false);
			}
			
			// mostrem banda color amb position
			TextView positionView = (TextView)view.findViewById(R.id.position);
			//positionView.setVisibility(View.VISIBLE);
			// bases
			if( POSITION_GUARDS.equals(position) )
			{
				positionView.setText(R.string.market_row_position_guard);
			}
			// alers
			else if( POSITION_FORWARDS.equals(position) )
			{
				positionView.setText(R.string.market_row_position_forward);
			}
			// pivots
			else 
			{
				positionView.setText(R.string.market_row_position_center);
				
			}
			
			// set team player balance
			String balance = cursor.getString(7);
			TextView balanceView = (TextView)view.findViewById(R.id.player_balance);
			balanceView.setText(balance);
			
			// set player team
			String team = cursor.getString(6);
			TextView teamView = (TextView)view.findViewById(R.id.player_team);
			teamView.setText(team);
			
			// set player vs team
			String vsTeam = cursor.getString(19);
			TextView vsTeamView = (TextView)view.findViewById(R.id.player_team_vs);
			vsTeamView.setText(vsTeam);
			
			// setejem l'avatar, la foto del jugador
			String cod = cursor.getString(11);
			ImageView avatarView = (ImageView)view.findViewById(R.id.avatar);
			imageDownloader.download(String.format(Supermanager.URL_PHOTO_PLAYER, cod), (ImageView) avatarView, defaultDrawable);
			
			// show buy button market_row_buy_button
			TextView favView = (TextView)view.findViewById(R.id.player_fav_button);
			Button favButton = (Button)view.findViewById(R.id.market_row_fav_button);
			favButton.setOnClickListener(new OnClickListener() 
			{
				public void onClick(View view) 
				{
					favPlayer(view);
				}
			});
			
			String fav = cursor.getString(20);
			// si el jugador esta a favorits
			if( fav != null && Supermanager.FAV_LISTNAME.equals(fav) )
			{
				favView.setVisibility(View.VISIBLE);
				favButton.setText(R.string.market_row_button_fav_remove);
			}
			else
			{
				favView.setVisibility(View.GONE);
				favButton.setText(R.string.market_row_button_fav_add);
			}
			favButton.setTag(R.id.player, cod);
			favButton.setTag(R.id.player_name,fav);
			
			// set player minutes
			TextView minutesView = (TextView) view.findViewById(R.id.player_minutes);
			if( minutesView != null )
			{
				String minutes = cursor.getString(21);
				minutesView.setText(minutes);
			}
			
			// set player price
			int price = cursor.getInt(9);
			TextView priceView = (TextView) view.findViewById(R.id.player_price);
			priceView.setText(intform.format(price)+"€");
			
			// set player average
			float average = cursor.getFloat(8);
			TextView averageView = (TextView) view.findViewById(R.id.player_average);
			averageView.setText(decform.format(average));
			
			// set player rating
			float rating = cursor.getFloat(14);
			TextView ratingView = (TextView) view.findViewById(R.id.player_rating);
			ratingView.setText(decform.format(rating));
			
			// set player rating last 3 games
			float ratingLast3Games = cursor.getFloat(15);
			TextView ratingLast3GamesView = (TextView) view.findViewById(R.id.player_rating_last3_games);
			ratingLast3GamesView.setText(decform.format(ratingLast3Games));
			
			// set player increase 15
			float increase15 = cursor.getFloat(16);
			TextView increase15View = (TextView) view.findViewById(R.id.player_increase_15);
			increase15View.setText(decform.format(increase15));
			
			// set player keep price
			float keepPrice = cursor.getFloat(17);
			TextView keepPriceView = (TextView) view.findViewById(R.id.player_keep_price);
			keepPriceView.setText(decform.format(keepPrice));
			
			// set player decrease 15
			float decrease15 = cursor.getFloat(18);
			TextView decrease15View = (TextView) view.findViewById(R.id.player_decrease_15);
			decrease15View.setText(decform.format(decrease15));
			
			// show info view if needed
			String info = cursor.getString(5);
			TextView infoView = (TextView)view.findViewById(R.id.player_info_button);
			Button infoButton = (Button)view.findViewById(R.id.market_row_info_button);
			infoButton.setOnClickListener(new OnClickListener() 
			{
				public void onClick(View view) 
				{
					showPlayerInfo(view);
				}
			});
			if( info == null )
			{
				infoView.setVisibility(View.GONE);
				infoButton.setVisibility(View.GONE);
			}
			else
			{
				infoView.setVisibility(View.VISIBLE);
				infoButton.setVisibility(View.VISIBLE);
				infoButton.setTag(info);
			}
			
			// si te status, cal ficar stick corresponent
			String status = cursor.getString(2);
			View stickView = view.findViewById(R.id.stick);
			if( "lesio.png".equals(status) )
			{
				stickView.setVisibility(View.VISIBLE);
				ImageView statusView = (ImageView)stickView;
				statusView.setImageResource(R.drawable.lesio);
				statusView.bringToFront();
			}
			else if( "semafor.png".equals(status) )
			{
				stickView.setVisibility(View.VISIBLE);
				ImageView statusView = (ImageView)stickView;
				// TODO: guardar drawable de semafor
				statusView.setImageResource(R.drawable.lesio);        				
				statusView.bringToFront();
			}
			// altrament mirem si te nationality
			else
			{
				// si te nacionality, cal ficar stick corresponent
				String nacionality = cursor.getString(3);
				if( "nacional.png".equals(nacionality) )
				{
					stickView.setVisibility(View.VISIBLE);
					ImageView statusView = (ImageView)stickView;
					statusView.setImageResource(R.drawable.nacional);
					statusView.bringToFront();
				}
				else if( "extra.png".equals(nacionality) )
				{
					stickView.setVisibility(View.VISIBLE);
					ImageView statusView = (ImageView)stickView;
					statusView.setImageResource(R.drawable.extra);        				
					statusView.bringToFront();
				}
				else
				{
					stickView.setVisibility(View.INVISIBLE);
				}
			}
		}
		
		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) 
		{
			// create the new view
			LayoutInflater inflater = LayoutInflater.from(context);
			ViewFlipper row = (ViewFlipper)inflater.inflate(R.layout.market_row, parent, false);
			
			// bind data to the row view
			//bindView(row, context, cursor);	
			
			// if we have player and actions on it, register fling listener
			row.setOnTouchListener(new View.OnTouchListener() 
	        {
	            public boolean onTouch(View v, MotionEvent event) 
	            {
	            	if( showingPlayerInfo )
	            		return true;
	            	
	            	//Log.d(TAG,"MarketAdapter.View.OnTouchListener.onTouch class: "+v.getClass().getName());
	            	
	            	// register row flipper to access it on gesture detector
	            	mySimpleOnGestureListener.setViewFlipper((ViewFlipper)v);
	    			
	            	if (myGestureDetector.onTouchEvent(event)) {
	                    return true;
	                }
	                return false;
	            }
	        });
			
			return row;
		}
	}
    
    public void onChangeFilter(String filter)
    {
    	Log.d(Supermanager.TAG, "MarketListFragment.onChangeFilter... position: "+position+", filter: "+filter);
    	// canviar el filtre i fer un restartLoader nomes si ha canviat el filter
    	if( mFilter == null && mFilter == filter )
    	{
    		;
    	}
    	else if( mFilter != null && mFilter.equals(filter) )
    	{
    		;
    	}
    	else
    	{
    		mFilter = filter;
        	
    		// restart the loader
    		getLoaderManager().restartLoader(LIST_LOADER, null, this);
    	}
    }
	
	public Loader<Cursor> onCreateLoader(int id, Bundle bundle) 
	{
		String selection = "";
		ArrayList<String> selectionArgsList = new ArrayList<String>();
		
		selection = Supermanager.Market.POSITION + " = ? AND "+
				Supermanager.Market.DAY + " = ? ";
		selectionArgsList.add(position);
		selectionArgsList.add(jornada);
		
		if( buyPosition != null )
		{
			selection += " AND "+Supermanager.Market.SHOWN_IN_BUY + " = ? ";
			selectionArgsList.add("1");
		}
		
		if( mFilter != null )
		{
			selection += "AND "+Supermanager.PlayerList.LIST_NAME + " = ? ";
			selectionArgsList.add(mFilter);
		}
		
		String[] selectionArgs = new String[selectionArgsList.size()];
		selectionArgs = selectionArgsList.toArray(selectionArgs);
		
		CursorLoader cursorLoader = new CursorLoader(getActivity(),
				Supermanager.Market.CONTENT_URI, 
				PROJECTION, 
				selection, 
				selectionArgs, 
				order);
	    return cursorLoader;
	}

	public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) 
	{
		adapter.swapCursor(cursor);
	}

	public void onLoaderReset(Loader<Cursor> cursor) 
	{
		adapter.swapCursor(null);
	}

}
